package com.beardedhen.harmonybootstrap;

import com.beardedhen.harmonybootstrap.api.attributes.BootstrapBrand;
import com.beardedhen.harmonybootstrap.api.defaults.DefaultBootstrapSize;
import com.beardedhen.harmonybootstrap.api.view.BootstrapBrandView;
import com.beardedhen.harmonybootstrap.api.view.BootstrapSizeView;
import com.beardedhen.harmonybootstrap.api.view.BorderView;
import com.beardedhen.harmonybootstrap.utils.ResUtil;

import ohos.agp.components.AttrSet;
import ohos.agp.components.Image;
import ohos.agp.components.element.Element;
import ohos.agp.render.Paint;
import ohos.agp.utils.Color;
import ohos.app.Context;
import ohos.media.image.PixelMap;
import ohos.media.image.common.PixelFormat;

/**
 * Parent class of Circle and Square Thumbnails - contains boilerplate code required to get
 * BootstrapBrand and borders working via getters/setters. Also overrides ImageView so that only
 * CENTER_CROP is allowed, and a callback is fired whenever the image source changes.
 */
abstract class BootstrapBaseThumbnail extends Image implements BootstrapBrandView, BorderView, BootstrapSizeView {

    protected BootstrapBrand bootstrapBrand;

    protected boolean hasBorder;

    protected float baselineBorderWidth;

    protected float baselineOuterBorderWidth;

    protected float bootstrapSize;

    protected PixelMap sourceBitmap;

    protected final Paint placeholderPaint = new Paint();

    protected final Paint borderPaint = new Paint();

    protected final Paint imagePaint = new Paint();

    private static final PixelFormat BITMAP_CONFIG = PixelFormat.ARGB_8888;

    public BootstrapBaseThumbnail(Context context) {
        super(context);
        initialise(null);
    }

    public BootstrapBaseThumbnail(Context context, AttrSet attrs) {
        super(context, attrs);
        initialise(attrs);
    }

    public BootstrapBaseThumbnail(Context context, AttrSet attrs, String defStyle) {
        super(context, attrs, defStyle);
        initialise(attrs);
    }

    protected void initialise(AttrSet attrs) {
        baselineOuterBorderWidth = ResUtil.getDimen(getContext(), ResourceTable.Float_bthumbnail_outer_stroke);
        baselineBorderWidth = ResUtil.getDimen(getContext(), ResourceTable.Float_bthumbnail_default_border);
        setupPaints();
        updateImageState();
    }

    private void setupPaints() {
        Color strokeColor = new Color(bootstrapBrand.defaultEdge(getContext()));
        int placeholderColor = ResUtil.getColor(getContext(), ResourceTable.Color_bootstrap_gray_light);

        borderPaint.setColor(strokeColor);
        borderPaint.setAntiAlias(true);
        borderPaint.setStrokeWidth(baselineBorderWidth);
        borderPaint.setStyle(Paint.Style.STROKE_STYLE);
        imagePaint.setAntiAlias(true);

        placeholderPaint.setColor(new Color(placeholderColor));
        placeholderPaint.setAntiAlias(true);
        placeholderPaint.setStyle(Paint.Style.FILL_STYLE);
    }

    @Override
    public void setScaleMode(ScaleMode scaleType) {
        if (scaleType != ScaleMode.CLIP_CENTER) {
            throw new IllegalArgumentException("Only CenterCrop is currently supported by this view");
        } else {
            super.setScaleMode(scaleType);
        }
    }

    @Override
    public ScaleMode getScaleMode() {
        return ScaleMode.CLIP_CENTER;
    }

    /*
     * Image setter overrides
     */

    @Override
    public void setPixelMap(int resId) {
        super.setPixelMap(resId);
        sourceBitmap = getPixelMap();
        updateImageState();
    }

    @Override
    public void setPixelMap(PixelMap pixelMap) {
        pixelMap = ResUtil.getScaledPixelMap(getContext(), pixelMap);
        super.setPixelMap(pixelMap);
        sourceBitmap = pixelMap;
        updateImageState();
    }

    @Override
    public void setImageElement(Element element) {
        super.setImageElement(element);
        sourceBitmap = getPixelMap();
        updateImageState();
    }

    /**
     * Called when the ImageView should alter its source bitmap, then invalidate itself.
     */
    protected abstract void updateImageState();

    /*
     * Getters/Setters
     */

    @Override
    public void setBootstrapBrand(BootstrapBrand bootstrapBrand) {
        this.bootstrapBrand = bootstrapBrand;
        updateImageState();
    }

    @Override
    public BootstrapBrand getBootstrapBrand() {
        return bootstrapBrand;
    }

    @Override
    public void setBorderDisplayed(boolean displayed) {
        hasBorder = displayed;
        updateImageState();
    }

    @Override
    public boolean isBorderDisplayed() {
        return hasBorder;
    }

    @Override
    public float getBootstrapSize() {
        return bootstrapSize;
    }

    @Override
    public void setBootstrapSize(float bootstrapSize) {
        this.bootstrapSize = bootstrapSize;
        updateImageState();
    }

    @Override
    public void setBootstrapSize(DefaultBootstrapSize bootstrapSize) {
        setBootstrapSize(bootstrapSize.scaleFactor());
    }

}